7-2 nestjs集成cache-manager与ioredis
本节目标
将 cache-manager 的 Store 后端从内存切换为 ioredis,实现支持持久化的生产级缓存方案,并理解 cache-manager 与自建 RedisModule 的适用场景差异。
背景与选型
官方的 cache-manager-redis-store 不支持 Redis v4+,因此 NestJS 官方推荐使用 @anthony212/cache-manager-ioredis-yet(简称 cache-manager-ioredis-yet)作为 ioredis 的 Store 适配层。
版本对应关系:
| 库 | 版本 | 说明 |
|---|---|---|
cache-manager | v5.x | TTL 单位为毫秒 |
ioredis | v5.3+ | 完整支持 Redis Cluster / Sentinel |
cache-manager-ioredis-yet | 最新 | 官方推荐的 ioredis Store |
安装依赖
pnpm add cache-manager-ioredis-yet
bash
该包会自动依赖 ioredis,如果项目中已有 ioredis,确保版本在 5.x 以上。
集成配置
步骤一:导入 redisStore 函数
import { redisStore } from 'cache-manager-ioredis-yet';
typescript
可通过查看该包的
src/index.ts确认导出的方法列表,其中包含redisStore函数。
步骤二:在 CacheModule 中配置 Store
// app.module.ts
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-ioredis-yet';
@Module({
imports: [
CacheModule.register({
store: redisStore, // 直接传递函数引用,不是 await 的结果
host: 'localhost',
port: 6379,
password: 'example',
ttl: 30000, // 30秒(毫秒单位)
}),
],
})
export class AppModule {}
typescript
关键点:store 属性接收的是 redisStore 函数本身,而非 await redisStore() 的返回值。NestJS 的 CacheModule 内部会自行调用该函数来创建 Store 实例。
底层原理
查看 @nestjs/cache-manager 的源码,核心逻辑在 cache.provider.ts 的 createCacheManager 工厂函数中:
// cache.provider.ts(简化)
async function createCacheManager(options) {
const store = options.store;
if (typeof store === 'function') {
// store 是函数 -> 直接调用获取 Store 实例
const storeInstance = await store(options);
return new CacheManager(storeInstance);
}
if (typeof store === 'object') {
// store 是对象 -> 直接使用
return new CacheManager(store);
}
}
typescript
因此配置时传递函数引用是正确做法,CacheModule 的工厂方法会在运行时调用它。
验证测试
接口测试:使用之前的缓存接口,发送请求后在 Redis 客户端中验证数据已写入:
# 请求接口
GET /api/v2?token=222
# Redis 客户端验证
> KEYS *
1) "token"
> GET token
"\"222\""
text
TTL 验证:将 TTL 设为 30 秒,请求后等待 30 秒再次请求,确认缓存过期后重新执行路由逻辑。
cache-manager vs 自建 RedisModule
两种方案的对比:
| 维度 | cache-manager + ioredis | 自建 RedisModule (ioredis) |
|---|---|---|
| 集成复杂度 | 低,装饰器即可完成 | 中,需要手动封装 |
| 接口缓存 | @CacheInterceptor 开箱即用 | 需手动实现拦截逻辑 |
| TTL 控制 | @CacheTTL 装饰器细粒度控制 | 手动调用 expire 命令 |
| Redis 高级功能 | 仅支持基本 get/set/del | 支持 Pub/Sub、Stream、Lua 脚本、Cluster |
| 集群支持 | 有限 | 完整支持 |
| 微服务集成 | 不支持 | 支持 Redis 作为传输层 |
| 适用场景 | 接口缓存、短生命周期数据 | 分布式缓存、发布订阅、微服务通信 |
推荐使用策略
需要接口级缓存 + 简单 get/set?
|
+-- 是 --> 使用 cache-manager + ioredis Store
|
+-- 否 --> 需要 Redis 高级功能?
|
+-- 是 --> 使用自建 RedisModule (ioredis)
|
+-- 否 --> 两者皆可,根据团队偏好选择
text
本节小结
- 掌握了
cache-manager-ioredis-yet的安装与集成方法。 - 理解了
store属性传递函数引用而非调用结果的原理。 - 学会了通过阅读源码理解框架内部工作机制的思路。
- 明确了
cache-manager方案与自建RedisModule的适用场景差异。 - 至此,NestJS 常用中间件中 Redis 相关的扩展介绍完毕。
↑